 MgState {
	classvar <>mgk;
	classvar <>white;
	classvar <>serial;
	classvar <>melodic;
	classvar <>reportHooks;
}

+ Main {
	*start {
		Act.initClass( debug: true );
		TempoClock.default = TempoClock.new( queueSize: 2048 );
		MgState.reportHooks = IdentityDictionary();
		MgState.mgk = MidiGlock().start{
			MgState.white = WhiteTone();
			MgState.serial = SerialTone();
			MgState.melodic = Melody();
		};
		Main.initHooks();
	}

	*initHooks {
		MgState.reportHooks.put( \tare,
			ReportHook(
				ele: {
					| x, i, j, state |
					if( state.at( \tareBuffs ), {
						MgState.mgk.sens[ i ][ j ] = max(
							MgState.mgk.sens[ i ][ j ],
							x.abs );
						state.put( \count, state.at( \count ) + 1 );
						if( state.at( \count ) > state.at( \limit ),
							{ state.put( \tareBuffs, false ) } ) } ) },
				st: ( tareBuffs: false, count: 0, limit: 10 ) ) );
		MgState.reportHooks.put( \getStrips,
			ReportHook(
				ele: {
					| x, i, j, state |
					if( i != j, {
						MgState.mgk.strips[ i ] =
						MgState.mgk.strips[ i ] + x.abs } ) } ) );
					/*					if( x.abs > MgState.mgk.sens[ i ][ j ], {
						MgState.mgk.strips[ i ].add( j )
					}, {
						MgState.mgk.strips[ i ].remove( j ) } ) } ) );
					*/
		MgState.reportHooks.put( \trace,
			ReportHook(
				st: ( max: [ 0, -1 ], count: 0, print: false ),
				raw: { | x, state |
					state.put( \count, ( state.at( \count )+ 1 ) % 60 );
					if( and( state.at( \print ), state.at( \count ) == 0 ), {
						[
							\maximum,
							state.at( \max ),
							MgState.mgk.strips
						].postln;
						state.put( \max, [ 0, -1 ] ) } ) },
				col: { | x, i, state |
					if( and( state.at( \print ), state.at( \count ) == 0),
						{ x.postln } ) },
				ele: { | x, i, j, state |
					if( state.at( \print ), {
						if( and( i != j, x.abs > state.at( \max )[ 0 ] ), {
							state.put( \max, [ x.abs, i, j ] ) } ) } ) } ) );
		if( MgState.mgk.testing, {
			MgState.reportHooks.put( \display,
				ReportHook(
					ele: { | x, i, j, state |
						var shade = min( x/100, 1 );
						MgState.mgk.show( i, j,
							bg: Color( shade, shade, shade ),
							fg: if( shade > 0.5, Color.black, Color.white ),
							num: if( x.abs > MgState.mgk.sens[ i ][ j ],
								x, 0 ) ) } ) ) } );
		MgState.reportHooks.put( \playback,
			Act( #[ 4, 0 ], 10, { | x | x }, { MgState.melodic.play },
				"melodic starts" );
			Act( #[ 4, 1 ], 10, { | x | x }, { MgState.serial.play },
				"serial starts" );
			Act( #[ 4, 2 ], 10, { | x | x }, { MgState.white.play },
				"white starts" );
			Act( #[ 7, 0 ], 10, { | x | x }, { MgState.melodic.play },
				"melodic stops" );
			Act( #[ 7, 1 ], 10, { | x | x }, { MgState.serial.stop },
				"serial stops" );
			Act( #[ 7, 2 ], 10, { | x | x }, { MgState.white.stop },
				"white stops" );
			ReportHook(
				raw:  { | x, state |
					Act.run( MgState.mgk.strips ) } ) );
	}

	*tare{
		MgState.reportHooks.at( \tare ).put( \tareBuffs, true );
	}

	*trace{ | should = true |
		MgState.reportHooks.at( \trace ).put( \print, should );
	}
	
	*unmonitor {
		MgState.mgk.monitor.stop
	}

	*monitor {
		MgState.mgk.monitor.reset;
		MgState.mgk.monitor.play
	}

	*monitoring {
		^MgState.mgk.monitor.isPlaying
	}

	*playing {
		^Tones.all.collect(_.isPlaying)
	}
}
